﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Collections;
using DBConnectionLib;
using System.Configuration;
using System.Windows.Forms;
using DBSourceToolsLib.Interfaces;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using StructureMap;

namespace DBSourceToolsLib
{
    public class UserSettings
    {

        const string STR_ProjectBaseDirectory = "ProjectBaseDirectory=";
        const string STR_DefaultDatabase = "DefaultDatabase=";
        const string STR_UseANSIEncoding = "UseANSIEncoding=";
        const string STR_UseExtendedProperties = "UseExtendedProperties=";
        const string STR_UseIsql = "UseIsql=";
        const string STR_DisableIntellisense = "DisableIntellisense=";

        private static UserSettings m_Singleton;
        private static bool m_Created = false;
        public bool UseANSII;
        public bool UseExtendedProperties;
        public bool UseIsql;
        public bool DisableIntellisense = false;
        
        private string m_BaseDirectory = "c:\\source\\DBSourceTools";
        private Hashtable m_HashRecentFiles = new Hashtable();
        private string m_LastConfigFile = "";
        private SourceDatabase m_DefaultDatabase;
        private string m_StartupPath;
        private string m_CurrentDbNickName;
        private SourceDatabase m_CurrentSourceDatabase;
        public bool ProjectNeedsSaving { get; set; }
        //public bool ProjectNeedsWriteTargets { get; set; }

        private IAppSettings _appSettings;

        public SourceDatabase CurrentSourceDatabase
        {
            get { return m_CurrentSourceDatabase; }
            set { m_CurrentSourceDatabase = value; }
        }
        

        public string AppConfigFile
        {
            get { return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\DBSourceTools\\DBSourceTools.config"; }
        }

        public string CurrentDbNickName
        {
            get { return m_CurrentDbNickName; }
            set {
                m_CurrentDbNickName = value;
                m_CurrentSourceDatabase = this.getSourceDatabase(m_CurrentDbNickName);
            }
        }
        private DatabaseProject m_DatabaseProject = null;

        public DatabaseProject DatabaseProject
        {
            get { return this.m_DatabaseProject; }
            set { 
                this.m_DatabaseProject = value;
                this.m_CurrentDbNickName = m_DatabaseProject.SourceDatabases[0].NickName;
            }
        }

        public string StartupPath
        {
            get { return m_StartupPath; }
            set { m_StartupPath = value; }
        }

        public string LastProjectConfigFile
        {
            get { return m_LastConfigFile; }
            set { m_LastConfigFile = value; }
        }

        #region getters_and_setters

        public string ProjectBaseDirectory
        {
            get { return m_BaseDirectory; }
            set { m_BaseDirectory = value; }
        }
        #endregion getters_and_setters

        private UserSettings()
        {
            m_Singleton = this;
            m_Created = true;
            UseANSII = false;
            UseExtendedProperties = false;
            _appSettings = ObjectFactory.GetInstance<IAppSettings>();

            //SocketToolsLib.SocketSender.Instance().SetIpAddress("127.0.0.1");
            //SocketToolsLib.SocketSender.Instance().SetPort(11000);

        }
        public static UserSettings Instance()
        {
            if (!m_Created)
                m_Singleton = new UserSettings();
            return m_Singleton;
        }
        public bool InstanceFlag
        {
            get { return m_Created; }
        }

        public SourceDatabase getSourceDatabase(string strDbName)
        {
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), strDbName);
            foreach (SourceDatabase oSource in DatabaseProject.SourceDatabases)
            {
                if (oSource.NickName.CompareTo(strDbName) == 0)
                    return oSource;
            }
                return null;
        }
        
        public void AddRecentFile(string strObject)
        {
            if (!m_HashRecentFiles.ContainsKey(strObject))
            {
                m_HashRecentFiles.Add(strObject, strObject);
            }
        }

        public IEnumerable<string> RecentFiles
        {
            get
            {
                foreach (Object oObject in this.m_HashRecentFiles.Keys)
                    yield return (string)oObject;
            }
        }

        public void SaveRecentFileList()
        {
            //System.Configuration.Configuration oConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            //string strBaseDir = oConfig.FilePath.Substring(0, oConfig.FilePath.LastIndexOf("\\"));
            //using (System.IO.StreamWriter oWriter = new System.IO.StreamWriter(strBaseDir + @"\DBSourceToolsRecent.txt"))
            //{
            //    foreach (string strFileName in this.RecentFiles)
            //    {
            //        oWriter.WriteLine(strFileName);
            //    }
            //}
        }


        public void LoadRecentFiles()
        {
            //System.Configuration.Configuration oConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            //string strBaseDir = oConfig.FilePath.Substring(0, oConfig.FilePath.LastIndexOf("\\"));
            //if (System.IO.File.Exists(strBaseDir + @"\DBSourceToolsRecent.txt"))
            //{
            //    using (System.IO.StreamReader oReader = new System.IO.StreamReader(strBaseDir + @"\DBSourceToolsRecent.txt"))
            //    {
            //        string strFileName;
            //        while ((strFileName = oReader.ReadLine()) != null)
            //        {
            //            this.AddRecentFile(strFileName);
            //        }
            //    }
            //}
        }

        public void ClearRecentFiles()
        {
            this.m_HashRecentFiles.Clear();
        }

        public void RemoveRecentFile(string strObject)
        {
            if (this.m_HashRecentFiles.ContainsKey(strObject))
                this.m_HashRecentFiles.Remove(strObject);
        }

        public void SaveConfig()
        {
            string strConfig = String.Format("{0}\\{1}.dbsp", this.ProjectBaseDirectory, this.DatabaseProject.ProjectName);

//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), strConfig);

            //SaveConfig(this.ProjectBaseDirectory + "\\" + this.DatabaseProject.ProjectName + ".dbsp");
            SaveConfig(strConfig);

        }

        public void SaveConfig(string strConfigFile)
        {
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), strConfigFile);
            this.LastProjectConfigFile = strConfigFile;
            FileUtils.EnsureFileIsWriteable(strConfigFile);
            using (System.IO.StreamWriter oStreamWriter = new System.IO.StreamWriter(strConfigFile))
            {
                oStreamWriter.WriteLine(STR_ProjectBaseDirectory + this.ProjectBaseDirectory);
                oStreamWriter.WriteLine(STR_DefaultDatabase + this.m_CurrentDbNickName);
                oStreamWriter.WriteLine(STR_UseANSIEncoding + this.UseANSII);
                oStreamWriter.WriteLine(STR_UseExtendedProperties + this.UseExtendedProperties);
                oStreamWriter.WriteLine(STR_UseIsql + this.UseIsql);
                oStreamWriter.WriteLine(STR_DisableIntellisense + this.DisableIntellisense);

            }
            try
            {
                WriteAppConfig();
            }
            catch (System.NullReferenceException nullEx)
            {
                throw new Exception(" Could not save config setting LastConfigFile " + nullEx.ToString());
            }
        }

        public void LoadLastProjectConfigFile()
        {

//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), this.LastProjectConfigFile);
            if (System.IO.File.Exists(this.LastProjectConfigFile))
            {
                using (System.IO.StreamReader oStreamReader = new System.IO.StreamReader(this.LastProjectConfigFile))
                {
                    string strProjectName = this.LastProjectConfigFile.Substring(LastProjectConfigFile.LastIndexOf("\\") + 1);
                    strProjectName = strProjectName.Substring(0, strProjectName.LastIndexOf(".dbsp"));
                    string strReadLine;
                    while ((strReadLine = oStreamReader.ReadLine()) != null)
                    {
                        if (strReadLine.Contains(STR_ProjectBaseDirectory))
                        {
                            this.ProjectBaseDirectory = strReadLine.Substring(STR_ProjectBaseDirectory.Length);
                                if (m_DatabaseProject != null)
                                    m_DatabaseProject = null;

                            string projectName = "";
                            string projectBaseDir = "";

                            FileUtils.ParseProjectFileName(this.LastProjectConfigFile, out projectName, out projectBaseDir);

                            if (projectBaseDir != this.ProjectBaseDirectory)
                            {
                                // TODO: NERO: show warning to user that this project has moved ?

                                if (_appSettings.IsGuiRunning)
                                {
                                    string message =
                                        string.Format(
                                            "The project {0} seems to have been moved.\n\nOriginal Disk Location: {1}.\nCurrent Disk Location: {2}\n\nDo you wish to reload this project from the current location ?",
                                            projectName, ProjectBaseDirectory, projectBaseDir
                                            );
                                    if (MessageBox.Show(message, "Reload Project", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                    {
                                        _appSettings.AutoReload = true;
                                    }
                                }
                                else
                                {
                                    Console.WriteLine(
                                    string.Format(
                                        "The project {0} seems to have been moved from {1} to {2}.\n Loading files from {2}",
                                        projectName, ProjectBaseDirectory, projectBaseDir
                                        )
                                    );
                                    _appSettings.AutoReload = true;
                                }

                                if (_appSettings.AutoReload)
                                {
                                    this.ProjectBaseDirectory = projectBaseDir;
                                    ProjectNeedsSaving = true;
                                }
                            }

                            m_DatabaseProject = new DatabaseProject(this.ProjectBaseDirectory, strProjectName);
                                m_DatabaseProject.LoadFromDisk(false);

                        }
                        if (strReadLine.Contains(STR_DefaultDatabase))
                            this.m_CurrentDbNickName = strReadLine.Substring(STR_DefaultDatabase.Length);
                        if (strReadLine.Contains(STR_UseANSIEncoding))
                            this.UseANSII = Boolean.Parse(strReadLine.Substring(STR_UseANSIEncoding.Length));
                        if (strReadLine.Contains(STR_UseExtendedProperties))
                            this.UseExtendedProperties = Boolean.Parse(strReadLine.Substring(STR_UseExtendedProperties.Length));
                        if (strReadLine.Contains(STR_UseIsql))
                            this.UseIsql = Boolean.Parse(strReadLine.Substring(STR_UseIsql.Length));
                        if (strReadLine.Contains(STR_DisableIntellisense))
                            this.DisableIntellisense = Boolean.Parse(strReadLine.Substring(STR_DisableIntellisense.Length));

                    }
                }
            }
            
        }

        public void LoadLastProjectConfigFile(string strConfigFileName)
        {
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), strConfigFileName);
            this.LastProjectConfigFile = strConfigFileName;
            LoadLastProjectConfigFile();
        }

        public void CloseProject()
        {
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), "");
            DatabaseProject.WriteProjectFile();
            DatabaseProject.CloseProject();
            this.m_DatabaseProject = null;
            this.m_CurrentDbNickName = "";

        }

        public void LoadAppConfig()
        {
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), AppConfigFile);
            if (!System.IO.File.Exists(AppConfigFile))
                WriteAppConfig();
            using (System.IO.StreamReader oReader = new System.IO.StreamReader(AppConfigFile))
            {
                string strLine = oReader.ReadLine();
                if (!String.IsNullOrEmpty(strLine))
                {
                    string strLastConfig = "LastConfigFile=";
                    if (strLine.Contains(strLastConfig))
                    {
                        this.LastProjectConfigFile = strLine.Substring(strLastConfig.Length);
                    }
                }
            }
            LoadLastProjectConfigFile();
        }

        public void WriteAppConfig()
        {
            
            string strConfigFileDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\DBSourceTools";
//            SocketToolsLib.SocketSender.Instance().SendUDPMessage(System.Reflection.MethodBase.GetCurrentMethod(), strConfigFileDir);
            if (!System.IO.Directory.Exists(strConfigFileDir))
            {
                System.IO.Directory.CreateDirectory(strConfigFileDir);
                using (System.IO.StreamWriter oWriter = new System.IO.StreamWriter(UserSettings.Instance().AppConfigFile))
                {
                    oWriter.WriteLine("LastConfigFile=" + this.LastProjectConfigFile);
                }
            }
            else
            {
                FileUtils.EnsureFileIsWriteable(AppConfigFile);
                using (System.IO.StreamWriter oWriter = new System.IO.StreamWriter(AppConfigFile))
                {
                    oWriter.WriteLine("LastConfigFile=" + this.LastProjectConfigFile);
                }
            }
        }
    }
}
